package org.zasadnyy.redlions.players.client.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.zasadnyy.redlions.players.shared.model.PlayerItem;
import org.zasadnyy.redlions.players.shared.model.TournamentItem;
import org.zasadnyy.redlions.players.shared.remote.PlayersCrudRemote;
import org.zasadnyy.redlions.players.shared.remote.PlayersCrudRemoteAsync;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.DateBox;
import com.smartgwt.client.util.SC;

public class PlayerEditPanel extends Composite implements
		HasValueChangeHandlers<PlayerItem> {

	interface MyUiBinder extends UiBinder<Widget, PlayerEditPanel> {
	}

	private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);

	@UiField
	TextBox nameField;
	@UiField
	TextBox surnameField;
	@UiField
	TextBox photoUrlField;
	@UiField
	TextBox nativeCityField;
	@UiField
	DateBox birthdayField;
	@UiField
	DateBox playsFromField;
	@UiField
	Button createButton;
	@UiField
	CheckBoxGroup tournamentsField;

	private PlayersCrudRemoteAsync servise = GWT
			.create(PlayersCrudRemote.class);
	private PlayerItem player = new PlayerItem();

	public PlayerEditPanel() {
		initWidget(uiBinder.createAndBindUi(this));

		DateTimeFormat birthdayDateFormat = DateTimeFormat
				.getFormat(PredefinedFormat.DATE_LONG);
		birthdayField.setFormat(new DateBox.DefaultFormat(birthdayDateFormat));

		DateTimeFormat playesFromDateFormat = DateTimeFormat
				.getFormat(PredefinedFormat.YEAR_MONTH);
		playsFromField
				.setFormat(new DateBox.DefaultFormat(playesFromDateFormat));
	}

	public void setPlayer(PlayerItem player) {

		if (player != null) {
			this.player = player;

			nameField.setText(player.getName());
			surnameField.setText(player.getSurname());
			photoUrlField.setText(player.getPhotoUrl());
			nativeCityField.setText(player.getNativeCity());
			birthdayField.setValue(player.getBirtday());
			playsFromField.setValue(player.getPlaysFrom());

			tournamentsField.setCheckBoxes(player.getTournaments());
		} else {
			this.player = new PlayerItem();

			nameField.setText("");
			surnameField.setText("");
			photoUrlField.setText("");
			nativeCityField.setText("");
			birthdayField.setValue(null);
			playsFromField.setValue(null);

			tournamentsField.setCheckBoxes();

		}
	}

	public PlayerItem getPlayer() {
		return syncPlayerFields();
	}

	private PlayerItem syncPlayerFields() {
		player.setName(nameField.getText());
		player.setSurname(surnameField.getText());
		player.setNativeCity(nativeCityField.getText());
		player.setPhotoUrl(photoUrlField.getText());
		player.setBirtday(birthdayField.getValue());
		player.setPlaysFrom(playsFromField.getValue());

		List<TournamentItem> selectedItems = tournamentsField
				.getSelectedItems();
		Map<Integer, List<TournamentItem>> groupedTournaments = new HashMap<Integer, List<TournamentItem>>();
		if (selectedItems != null) {
			for (TournamentItem tournament : selectedItems) {
				@SuppressWarnings("deprecation")
				int year = tournament.getTime().getYear() + 1900;
				if (groupedTournaments.keySet().contains(year)) {
					groupedTournaments.get(year).add(tournament);
				} else {
					List<TournamentItem> itemsForYear = new ArrayList<TournamentItem>();
					itemsForYear.add(tournament);
					groupedTournaments.put(year, itemsForYear);
				}
			}
		} else {
			SC.warn("Set<Key> tournaments == NULL");
		}
		player.setTournaments(groupedTournaments);

		return player;
	}

	@Override
	public HandlerRegistration addValueChangeHandler(
			ValueChangeHandler<PlayerItem> handler) {
		return addHandler(handler, ValueChangeEvent.getType());
	}

	@UiHandler("createButton")
	void onCreateButtonClick(ClickEvent event) {
		// ValueChangeEvent.fire(this, null);
		setPlayer(null);
	}

	@UiHandler("saveButton")
	void onSaveButtonClick(ClickEvent event) {
		final PlayerItem changedPlayer = getPlayer();

		if (changedPlayer == null) {
			return;
		}

		servise.addOrEditPlayer(changedPlayer, new AsyncCallback<Void>() {

			@Override
			public void onSuccess(Void result) {
				ValueChangeEvent.fire(PlayerEditPanel.this, changedPlayer);
			}

			@Override
			public void onFailure(Throwable caught) {
				SC.warn(caught.getMessage());
			}
		});
	}

	@UiHandler("deleteButton")
	void onDeleteButtonClick(ClickEvent event) {
		servise.deletePlayerById(getPlayer().getId(),
				new AsyncCallback<Void>() {

					@Override
					public void onSuccess(Void result) {
						ValueChangeEvent.fire(PlayerEditPanel.this, null);
						setPlayer(null);
					}

					@Override
					public void onFailure(Throwable caught) {
						SC.warn("Things are bad. Exeption: "
								+ caught.getMessage());
					}
				});

	}

}
